#ifndef LASERPARAMS_H
#define LASERPARAMS_H

#include "laserdevice.h"
#include "galvoparams.h"
#include "delaybeamparams.h"
#include "wobbleparams.h"
#include "powerrampparams.h"
#include "markerparam.h"
#include "paramsidmanager.h"

class LaserParams : public JsonConvert
{
public:
    LaserParams(){
        mId = ParamsIDManager::getNewID();
    }

    void setParams(const LaserParams& param){
        this->mName = param.mName;
        this->mDescription = param.mDescription;
        this->mLaserDevice = param.mLaserDevice;
        this->mDelayBeamParams = param.mDelayBeamParams;
        this->mGalvoParams = param.mGalvoParams;
        this->mWobbleParams = param.mWobbleParams;
        this->mPowerRampParams = param.mPowerRampParams;
    }

    LaserDevice& laserDevice()
    {
        return mLaserDevice;
    }

    GalvoParams& galvoParams()
    {
        return mGalvoParams;
    }

    DelayBeamParams& delayBeamParams()
    {
        return mDelayBeamParams;
    }

    WobbleParams& wobbleParams()
    {
        return mWobbleParams;
    }

    PowerRampParams& powerRampParams()
    {
        return mPowerRampParams;
    }

    void readFromFile()
    {
        QSettings settings("GlobalLaser.ini", QSettings::IniFormat);
        settings.beginGroup("GlobalLaser");
        this->mName = settings.value("mName", "全局").toString();
        this->mDescription = settings.value("mDescription", "全局激光参数").toString();
        settings.endGroup();

        mLaserDevice.readFromFile();
        mGalvoParams.readFromFile();
        mDelayBeamParams.readFromFile();
        mWobbleParams.readFromFile();
        mPowerRampParams.readFromFile();
    }

    void writeToFile()
    {
        QSettings settings("GlobalLaser.ini", QSettings::IniFormat);
        settings.beginGroup("GlobalLaser");
        settings.setValue("mName", mName);
        settings.setValue("mDescription", mDescription);
        settings.endGroup();

        mLaserDevice.writeToFile();
        mGalvoParams.writeToFile();
        mDelayBeamParams.writeToFile();
        mWobbleParams.writeToFile();
        mPowerRampParams.writeToFile();
    }

    MarkerParam toMarkParams()
    {
        MarkerParam markerParam;
        LaserParam& laserParam = markerParam.laserParams();
        WobbleParam& wobbleParam = markerParam.wobbleParams();
        PowerRampParam& powerRamp = markerParam.powerRampParams();
        //RTC5中这里是半周期,单位是bit,周期 = 1000000 / Hz * 64;
        uint period = 1000000 / (mLaserDevice.frequency() * 1000) * 64;
        laserParam.setLaserMode((int)mLaserDevice.laserMode());
        laserParam.setFrequency(mLaserDevice.frequency() * 1000);
        laserParam.setPower(mLaserDevice.power());
        laserParam.setHalfPeriod(period / 2);
        //RTC5中这里是脉冲时间,单位是bit,时间 = 周期*占空比
        uint length;
        if(mLaserDevice.laserMode() == CO2){//如果是二氧化碳模式,则占空比=功率比
            length = (double)mLaserDevice.power() / 100 * period;
        }else{//如果是其它模式,比如使用8bit控制功率,则占空比始终为50%
            length = (double)0.5 * period;
        }

        laserParam.setPulseLength(length);
        //界面速度为mm/s,RTC为bit/ms所有要*k然后/1000;
        laserParam.setMarkSpeed(mLaserDevice.speed());
        laserParam.setJumpSpeed(mGalvoParams.jumpSpeed());
        laserParam.setJumpDelay(mDelayBeamParams.jumpDelay());
        laserParam.setMarkDelay(mDelayBeamParams.markDelay());
        laserParam.setPolygonDelay(mDelayBeamParams.polygonDelay());
        laserParam.setLaserOnDelay(mDelayBeamParams.laserOnDelay());
        laserParam.setLaserOffDelay(mDelayBeamParams.laserOffDelay());

        wobbleParam.setEnabled(mWobbleParams.enabled());
        if(wobbleParam.isEnabled()){
            wobbleParam.setTransversal(mWobbleParams.transversal());
            wobbleParam.setLongitudinal(mWobbleParams.longitudinal());
            wobbleParam.setFrequency(mWobbleParams.frequency());
            wobbleParam.setMode(0);
        }else{
            wobbleParam.setTransversal(0);
            wobbleParam.setLongitudinal(0);
            wobbleParam.setFrequency(0);
            wobbleParam.setMode(0);
        }
        powerRamp.setEnabled(mPowerRampParams.enable());
        powerRamp.setStartLevel(mPowerRampParams.startLevel());
        powerRamp.setEndLevel(mPowerRampParams.endLevel());
        powerRamp.setStartLength(mPowerRampParams.startLength());
        powerRamp.setEndLength(mPowerRampParams.endLength());
        return markerParam;
    }

    int id() const
    {
        return mId;
    }

    void setName(QString name)
    {
        mName = name;
    }

    QString name() const
    {
        return mName;
    }

    void setDescription(QString description)
    {
        mDescription = description;
    }

    QString description() const
    {
        return mDescription;
    }

    QJsonObject toJsonObj() const
    {
        QJsonObject obj;
        obj["mName"] = mName;
        obj["mDescription"] = mDescription;
        obj["mLaserDevice"] = mLaserDevice.toJsonObj();
        obj["mDelayBeamParams"] = mDelayBeamParams.toJsonObj();
        obj["mGalvoParams"] = mGalvoParams.toJsonObj();
        obj["mWobbleParams"] = mWobbleParams.toJsonObj();
        obj["mPowerRampParams"] = mPowerRampParams.toJsonObj();
        return obj;
    }

    void fromJsonObj(const QJsonObject& obj)
    {
        mName = obj["mName"].toString();
        mDescription = obj["mDescription"].toString();
        mLaserDevice.fromJsonObj(obj["mLaserDevice"].toObject());
        mDelayBeamParams.fromJsonObj(obj["mDelayBeamParams"].toObject());
        mGalvoParams.fromJsonObj(obj["mGalvoParams"].toObject());
        mWobbleParams.fromJsonObj(obj["mWobbleParams"].toObject());
        mPowerRampParams.fromJsonObj(obj["mPowerRampParams"].toObject());
    }

    void operator =(const LaserParams& param){
        this->mName = param.mName;
        this->mDescription = param.mDescription;
        this->mLaserDevice = param.mLaserDevice;
        this->mDelayBeamParams = param.mDelayBeamParams;
        this->mGalvoParams = param.mGalvoParams;
        this->mWobbleParams = param.mWobbleParams;
        this->mPowerRampParams = param.mPowerRampParams;
    }

    bool operator ==(const LaserParams& param){
        bool rel = true;
        rel &= (this->mName == param.mName);
        rel &= (this->mDescription == param.mDescription);
        rel &= (this->mLaserDevice == param.mLaserDevice);
        rel &= (this->mDelayBeamParams == param.mDelayBeamParams);
        rel &= (this->mGalvoParams == param.mGalvoParams);
        rel &= (this->mWobbleParams == param.mWobbleParams);
        rel &= (this->mPowerRampParams == param.mPowerRampParams);
        return rel;
    }

private:
    int mId = 0;
    QString mName = "";
    QString mDescription = "";
    LaserDevice mLaserDevice;
    GalvoParams mGalvoParams;
    DelayBeamParams mDelayBeamParams;
    WobbleParams mWobbleParams;
    PowerRampParams mPowerRampParams;
};

#endif // LASERPARAMS_H
